module time_delay_calc (
    input wire clk,                    // 系统时钟 50MHz
    input wire rst_n,                  // 异步复位
    input wire start_calc,             // 开始计算信号
    input wire [11:0] phi,             // 方位角 φ (12位，0-4095对应-90°到90°)
    input wire [11:0] theta,           // 俯仰角 θ (12位，0-4095对应-90°到90°)
    output reg [15:0] time_delays_0,   // 麦克风0的时延值 (单位：采样点)
    output reg [15:0] time_delays_1,
    output reg [15:0] time_delays_2,
    output reg [15:0] time_delays_3,
    output reg [15:0] time_delays_4,
    output reg [15:0] time_delays_5,
    output reg [15:0] time_delays_6,
    output reg [15:0] time_delays_7,
    output reg [15:0] time_delays_8,
    output reg [15:0] time_delays_9,
    output reg [15:0] time_delays_10,
    output reg [15:0] time_delays_11,
    output reg [15:0] time_delays_12,
    output reg [15:0] time_delays_13,
    output reg [15:0] time_delays_14,
    output reg [15:0] time_delays_15,  // 麦克风15的时延值 (单位：采样点)
    output reg calc_done,              // 计算完成信号
    output reg valid                   // 数据有效信号
);

// ============================================================================
// 系统参数
// ============================================================================
parameter D = 40;                      // 麦克风间距 40mm
parameter SOUND_SPEED = 343;           // 声速 343 m/s
parameter SAMPLE_RATE = 48000;         // 采样率 48kHz

// 预计算的常数: (SAMPLE_RATE * 1000) / SOUND_SPEED
// = 48000 * 1000 / 343 = 139883 (约等于 140000)
// 为了提高精度，使用定点数表示: 140 (整数部分)
// 实际计算: delay_samples = (distance_mm * 140) / 1000
parameter DELAY_SCALE = 140;           // 缩放因子 (samples per meter)

// ============================================================================
// 麦克风位置坐标定义（4x4阵列）
// ============================================================================
// 阵列布局:
//   Y
//   ^
//   |  12  13  14  15
//   |   8   9  10  11
//   |   4   5   6   7
//   |   0   1   2   3
//   +----------------> X

function [3:0] get_mic_pos_x;
    input [3:0] index;
    begin
        get_mic_pos_x = index[1:0];    // X坐标为列号(0-3)
    end
endfunction

function [3:0] get_mic_pos_y;
    input [3:0] index;
    begin
        get_mic_pos_y = index[3:2];    // Y坐标为行号(0-3)
    end
endfunction

// ============================================================================
// 三角函数查找表接口
// ============================================================================
wire signed [31:0] sin_phi, cos_phi, sin_theta, cos_theta;
wire trig_valid;

// 三角函数查找表实例化
trig_lookup_mem trig_lookup_inst (
    .clk(clk),
    .rst_n(rst_n),
    .angle_phi(phi),
    .angle_theta(theta),
    .sin_phi(sin_phi),
    .cos_phi(cos_phi),
    .sin_theta(sin_theta),
    .cos_theta(cos_theta),
    .trig_valid(trig_valid)
);

// ============================================================================
// 状态机定义
// ============================================================================
reg [2:0] state;
localparam IDLE        = 3'b000;
localparam TRIG_LOOKUP = 3'b001;
localparam CALC_DELAY  = 3'b010;
localparam NORMALIZE   = 3'b011;
localparam OUTPUT_DATA = 3'b100;
localparam DONE        = 3'b101;

// ============================================================================
// 内部寄存器
// ============================================================================
reg signed [31:0] distance_mm [0:15];  // 每个麦克风的路径差(mm)
reg [15:0] time_delays [0:15];         // 时延值(采样点数)
reg [3:0] calc_index;                  // 当前计算的麦克风索引
reg signed [31:0] min_distance;        // 最小距离(用于归一化)

// 临时计算变量
reg signed [31:0] mic_x_distance;      // X方向距离
reg signed [31:0] mic_y_distance;      // Y方向距离
reg signed [31:0] term1, term2;        // 中间计算结果
reg signed [31:0] distance_temp;       // 临时距离
reg [3:0] mic_x_pos;
reg [3:0] mic_y_pos;

// 循环变量
integer i;

// ============================================================================
// 主状态机
// ============================================================================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= IDLE;
        calc_done <= 1'b0;
        valid <= 1'b0;
        calc_index <= 4'b0;
        min_distance <= 32'h7FFFFFFF;  // 初始化为最大正数
        
        for (i = 0; i < 16; i = i + 1) begin
            time_delays[i] <= 16'b0;
            distance_mm[i] <= 32'b0;
        end
    end else begin
        case (state)
            // ================================================================
            // IDLE: 等待开始信号
            // ================================================================
            IDLE: begin
                valid <= 1'b0;
                calc_done <= 1'b0;
                calc_index <= 4'b0;
                min_distance <= 32'h7FFFFFFF;
                
                if (start_calc) begin
                    state <= TRIG_LOOKUP;
                end
            end
            
            // ================================================================
            // TRIG_LOOKUP: 等待三角函数查找完成
            // ================================================================
            TRIG_LOOKUP: begin
                if (trig_valid) begin
                    state <= CALC_DELAY;
                    calc_index <= 4'b0;
                end
            end
            
            // ================================================================
            // CALC_DELAY: 计算每个麦克风的路径差（流水线方式）
            // ================================================================
            CALC_DELAY: begin
                // 获取当前麦克风位置
                mic_x_pos = get_mic_pos_x(calc_index);
                mic_y_pos = get_mic_pos_y(calc_index);
                
                // 计算X方向分量: x * D * sin(φ) * cos(θ)
                // D的单位是mm，sin和cos是Q16.16格式  
                mic_x_distance = mic_x_pos * D;  // 单位: mm
                
                // term1 = sin(φ) * cos(θ) >> 16 (保持Q16.16精度)
                term1 = ($signed(sin_phi) * $signed(cos_theta)) >>> 16;
                
                // x_component = mic_x_distance * term1 >> 16
                term2 = ($signed(mic_x_distance) * term1) >>> 16;
                
                // 计算Y方向分量: y * D * sin(θ)
                mic_y_distance = mic_y_pos * D;  // 单位: mm
                
                // y_component = mic_y_distance * sin(θ) >> 16
                distance_temp = ($signed(mic_y_distance) * $signed(sin_theta)) >>> 16;
                
                // 总路径差 = x_component + y_component (单位: mm)
                distance_mm[calc_index] <= term2 + distance_temp;
                
                // 跟踪最小距离
                if ((term2 + distance_temp) < min_distance) begin
                    min_distance <= term2 + distance_temp;
                end
                
                // 处理下一个麦克风
                if (calc_index == 4'd15) begin
                    state <= NORMALIZE;
                    calc_index <= 4'b0;
                end else begin
                    calc_index <= calc_index + 1'b1;
                end
            end
            
            // ================================================================
            // NORMALIZE: 归一化时延（相对于最小时延）
            // ================================================================
            NORMALIZE: begin
                // 计算相对时延并转换为采样点数
                // delay_samples = (distance_mm - min_distance) * DELAY_SCALE / 1000
                // 使用移位来实现除以1000的近似: >> 10 ≈ / 1024
                
                distance_temp = distance_mm[calc_index] - min_distance;
                
                // 防止负数（理论上不应该出现）
                if (distance_temp < 0) begin
                    time_delays[calc_index] <= 16'b0;
                end else begin
                    // delay = (distance_temp * DELAY_SCALE) / 1000
                    // 为了精度，先乘后除
                    time_delays[calc_index] <= (distance_temp * DELAY_SCALE) / 1000;
                end
                
                if (calc_index == 4'd15) begin
                    state <= OUTPUT_DATA;
                end else begin
                    calc_index <= calc_index + 1'b1;
                end
            end
            
            // ================================================================
            // OUTPUT_DATA: 输出有效数据
            // ================================================================
            OUTPUT_DATA: begin
                valid <= 1'b1;
                state <= DONE;
            end
            
            // ================================================================
            // DONE: 计算完成，等待start_calc撤销
            // ================================================================
            DONE: begin
                calc_done <= 1'b1;
                valid <= 1'b0;
                if (!start_calc) begin
                    state <= IDLE;
                end
            end
            
            // ================================================================
            // DEFAULT: 返回IDLE
            // ================================================================
            default: begin
                state <= IDLE;
            end
        endcase
    end
end

// ============================================================================
// 输出端口映射（组合逻辑）
// ============================================================================
always @(*) begin
    time_delays_0  = time_delays[0];
    time_delays_1  = time_delays[1];
    time_delays_2  = time_delays[2];
    time_delays_3  = time_delays[3];
    time_delays_4  = time_delays[4];
    time_delays_5  = time_delays[5];
    time_delays_6  = time_delays[6];
    time_delays_7  = time_delays[7];
    time_delays_8  = time_delays[8];
    time_delays_9  = time_delays[9];
    time_delays_10 = time_delays[10];
    time_delays_11 = time_delays[11];
    time_delays_12 = time_delays[12];
    time_delays_13 = time_delays[13];
    time_delays_14 = time_delays[14];
    time_delays_15 = time_delays[15];
end

endmodule


